/* **********************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* This source code is subject to terms and conditions of the Shared Source License
* for DSL Editor PowerToy. A copy of the license can be found in the License.htm file
* at the root of this distribution. If you can not locate the Shared Source License
* for DSL Editor PowerToy, please obtain a copy from: http://www.codeplex.com/dsltreegrideditor/Project/License.aspx.
* By using this source code in any fashion, you are agreeing to be bound by
* the terms of the Shared Source License for DSL Editor PowerToy.
*
* You must not remove this notice, or any other, from this software.
*
* **********************************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing.Design;
using System.Text;
using System.Windows.Forms.Design;

using EnvDTE;

using Microsoft.Practices.ComponentModel;
using Microsoft.Practices.Common;
using Microsoft.Practices.RecipeFramework.Library.Editors;
using Microsoft.Practices.RecipeFramework;

namespace DslEditorPowerToy.ComponentModel.Design
{
    /// <summary>
    /// Editor for picking solution items
    /// </summary>
    public class SolutionItemPickerEditor : UITypeEditor
    {
        private SolutionItemPickerReference _reference;
        private bool _firstValue = false;
        private object _initialValue = null;
        private IWindowsFormsEditorService _formsService = null;

        #region Constructors
        public SolutionItemPickerEditor()
        {
            this._reference = new SolutionItemPickerReference();
        }
        #endregion

        #region Public Properties
        public override bool IsDropDownResizable
        {
            get
            {
                return true;
            }
        }
        #endregion

        #region Public Methods
        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            //Initialise the reference with attributes
            if (false == this._firstValue)
                InitialiseReference(context.PropertyDescriptor, this._reference);

            //Show picker
            DTE dte = (DTE)provider.GetService(typeof(DTE));
            using (SolutionPickerControl component = new SolutionPickerControl(dte, this._reference, value, context.PropertyDescriptor.PropertyType))
            {
                component.Site = new Site(provider, component, component.GetType().FullName);
                this._firstValue = true;
                this._initialValue = value;
                this._formsService = (IWindowsFormsEditorService)ServiceHelper.GetService(provider, typeof(IWindowsFormsEditorService), this);
                this._formsService.DropDownControl(component);
                this._formsService = null;

                //Check if no reference to query
                if (null != this._reference)
                {
                    bool flag = false;
                    try
                    {
                        flag = this._reference.IsEnabledFor(component.SelectedTarget);
                    }
                    catch (Exception exception)
                    {
                        throw new RecipeExecutionException(this._reference.AssetName, "Reference_FailEnabledFor", exception);
                    }
                    if (true == flag)
                        return component.SelectedTarget;

                    return null;
                }
            }

            return null;
        }
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.DropDown;
        }
        private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //Ensure a new selection
            if (((true == e.IsValid) 
                && (e.Selection == this._initialValue)) 
                && (true == this._firstValue))
            {
                this._firstValue = false;
            }
            else if (true == e.IsValid)
            {
                //Close the combo
                this._formsService.CloseDropDown();
            }
        }
        #endregion

        #region Private Methods
        /// <summary>
        /// Initialises reference with configuration of attributes
        /// </summary>
        /// <param name="context"></param>
        private void InitialiseReference(PropertyDescriptor descriptor, 
            SolutionItemPickerReference reference)
        {
            //Search for known attributes (only one instance possible)
            foreach (Attribute attribute in descriptor.Attributes)
            {
                if (attribute is SolutionItemPickerFilterAttribute)
                {
                    SolutionItemPickerFilterAttribute filterAttribute = attribute as SolutionItemPickerFilterAttribute;
                    reference.Filter = filterAttribute.Filter;
                    reference.ItemType = filterAttribute.ItemType;
                    break;
                }
            }
        }
        #endregion
    }
}
